﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Reflection;
using System.Web;

namespace ActionModel.Utility
{
	/// <summary>
	/// 字符串工具
	/// </summary>
	public class StringHelper
	{
		/// <summary>
		/// 给字符串中的字符添加转义符号，以便输出到客户端时得到原始字符串
		/// </summary>
		/// <param name="text"></param>
		/// <returns></returns>
		public static string GetOriginal(string text)
		{
			StringBuilder sb = new StringBuilder();
			char[] chars = text.ToCharArray();
			foreach (char c in chars)
			{
				switch ((ushort)c)
				{
					case 10:
						sb.Append("\\n");
						continue;
					case 13:
						sb.Append("\\r");
						continue;
					case 7:
						sb.Append("\\a");
						continue;
					case 8:
						sb.Append("\\b");
						continue;
					case 9:
						sb.Append("\\t");
						continue;
					case 0x0b:
						sb.Append("\\b");
						continue;
					case 34:
						sb.Append("\\\"");
						continue;
					case 39:
						sb.Append("\\\'");
						continue;
					case 92:
						sb.Append("\\\\");
						continue;
				}
				if ((ushort)c < 32 || (ushort)c == 127)
				{
					sb.Append("\\u" + ((ushort)c).ToString("x4"));
				}
				else
				{
					sb.Append(c);
				}
			}
			return sb.ToString();
		}

		/// <summary>
		/// 用实体替换模板，输出HTML
		/// </summary>
		/// <param name="ItemTemplate">模板内容</param>
		/// <param name="entity">实体对象</param>
		/// <param name="ItemIndex">索引号</param>
		/// <returns></returns>
		public static string TemplateReplaceWithItemIndex(string ItemTemplate, object entity, int ItemIndex)
		{
			return TemplateReplaceWithItemIndex(ItemTemplate, entity, ItemIndex, null);
		}
		/// <summary>
		/// 用实体替换模板，输出HTML
		/// </summary>
		/// <param name="ItemTemplate">模板内容</param>
		/// <param name="entity">实体对象</param>
		/// <param name="ItemIndex">索引号</param>
		/// <param name="ResultDict">选择输出</param>
		/// <returns>HTML</returns>
		public static string TemplateReplaceWithItemIndex(string ItemTemplate, object entity, int ItemIndex, Dictionary<string, bool> ResultDict)
		{
			ItemTemplate = ItemTemplate.Replace("[ItemIndex]", ItemIndex.ToString());

			Regex boolRegex = new Regex(@"\{\w+\?.*\|.*\}");
			MatchEvaluator boolMatchEvaluator = delegate(Match match)
			{
				if (entity == null) return string.Empty;

				string matchedString = match.Groups[0].Value;
				string[] parttexts = matchedString.Substring(1, matchedString.Length - 2).Split(new char[] { '{', '?', '|', '}' });
				if (parttexts[0] == "OddItemIndex")
				{
					if (ItemIndex % 2 == 1)
					{
						return parttexts[1];
					}
					else
					{
						return parttexts[2];
					}
				}
				else if (ResultDict != null && ResultDict.ContainsKey(parttexts[0]))
				{
					if (ResultDict[parttexts[0]])
					{
						return parttexts[1];
					}
					else
					{
						return parttexts[2];
					}
				}
				else
				{
					return matchedString;
				}
			};
			ItemTemplate = boolRegex.Replace(ItemTemplate, boolMatchEvaluator);

			Regex FieldRegex = new Regex(@"\[\w+(\.\w+(\(.*\))?)?\]");
			MatchEvaluator fieldMatchEvaluator = delegate(Match match)
			{
				if (entity == null) return string.Empty;

				string matchedString = match.Groups[0].Value;
				string fieldName = matchedString.Substring(1, matchedString.Length - 2).Split('.')[0];
				PropertyInfo pi = entity.GetType().GetProperty(fieldName, BindingFlags.Public | BindingFlags.Instance);
				if (pi == null) return "";
				object fieldValue = pi.GetValue(entity, null);
				if (match.Groups[1].Success)
				{
					if (match.Groups[2].Success)
					{
						string[] strs = match.Groups[1].Value.Split(new char[] { '.', '(', ')' });
						string methodName = strs[1];
						string[] paras = strs[2].Split(',');
						switch (methodName)
						{
							case "lenCut":
								{
									int len = fieldValue.ToString().Length;
									int.TryParse(paras[0], out len);
									if (len > 0 && len < fieldValue.ToString().Length)
									{
										return "<span title=\"" + HttpUtility.HtmlEncode(fieldValue.ToString()) + "\">" + fieldValue.ToString().Substring(0, len) + "...</span>";
									}
									else
									{
										return HttpUtility.HtmlEncode(fieldValue.ToString());
									}
								}
							default:
								return HttpUtility.HtmlEncode(fieldValue.ToString());
						}
					}
					else
					{
						string property = match.Groups[1].Value.Substring(1, match.Groups[1].Value.Length - 1);
						switch (property)
						{
							case "Date":
								{
									if (pi.PropertyType == typeof(DateTime))
									{
										DateTime dt = DateTime.Parse(fieldValue.ToString());
										return HttpUtility.HtmlEncode(dt.ToLongDateString());
									}
									else
									{
										return HttpUtility.HtmlEncode(fieldValue.ToString());
									}
								}
							case "Time":
								{
									if (pi.PropertyType == typeof(DateTime))
									{
										DateTime dt = DateTime.Parse(fieldValue.ToString());
										return HttpUtility.HtmlEncode(dt.ToLongTimeString());
									}
									else
									{
										return HttpUtility.HtmlEncode(fieldValue.ToString());
									}
								}
							default:
								return HttpUtility.HtmlEncode(((DateTime)fieldValue).ToString("f"));
						}
					}
				}
				else
				{
					return HttpUtility.HtmlEncode(fieldValue.ToString());
				}
			};
			ItemTemplate = FieldRegex.Replace(ItemTemplate, fieldMatchEvaluator);

			return ItemTemplate;
		}
		/// <summary>
		/// 用实体替换模板，输出HTML
		/// </summary>
		/// <param name="ItemTemplate">模板内容</param>
		/// <param name="entity">实体对象</param>
		/// <returns>HTML</returns>
		public static string TemplateReplace(string ItemTemplate, object entity)
		{
			return TemplateReplace(ItemTemplate, entity, null);
		}
		/// <summary>
		/// 用实体替换模板，输出HTML
		/// </summary>
		/// <param name="ItemTemplate">模板内容</param>
		/// <param name="entity">实体对象</param>
		/// <param name="ResultDict">输出选择</param>
		/// <returns></returns>
		public static string TemplateReplace(string ItemTemplate, object entity, Dictionary<string, bool> ResultDict)
		{
			Regex boolRegex = new Regex(@"\{\w+\?.*\|.*\}");
			MatchEvaluator boolMatchEvaluator = delegate(Match match)
			{
				if (entity == null) return string.Empty;

				string matchedString = match.Groups[0].Value;
				string[] parttexts = matchedString.Substring(1, matchedString.Length - 2).Split(new char[] { '{', '?', '|', '}' });
				if (ResultDict != null && ResultDict.ContainsKey(parttexts[0]))
				{
					if (ResultDict[parttexts[0]])
					{
						return parttexts[1];
					}
					else
					{
						return parttexts[2];
					}
				}
				else
				{
					return matchedString;
				}
			};
			ItemTemplate = boolRegex.Replace(ItemTemplate, boolMatchEvaluator);

			Regex FieldRegex = new Regex(@"\[\w+(\.\w+(\(.*\))?)?\]");
			MatchEvaluator fieldMatchEvaluator = delegate(Match match)
			{
				if (entity == null) return string.Empty;

				string matchedString = match.Groups[0].Value;
				string fieldName = matchedString.Substring(1, matchedString.Length - 2).Split('.')[0];
				PropertyInfo pi = entity.GetType().GetProperty(fieldName, BindingFlags.Public | BindingFlags.Instance);
				if (pi == null) return "";
				object fieldValue = pi.GetValue(entity, null);
				if (match.Groups[1].Success)
				{
					if (match.Groups[2].Success)
					{
						string[] strs = match.Groups[1].Value.Split(new char[] { '.', '(', ')' });
						string methodName = strs[1];
						string[] paras = strs[2].Split(',');
						switch (methodName)
						{
							case "lenCut":
								{
									int len = fieldValue.ToString().Length;
									int.TryParse(paras[0], out len);
									if (len > 0 && len < fieldValue.ToString().Length)
									{
										return "<span title=\"" + HttpUtility.HtmlEncode(fieldValue.ToString()) + "\">" + fieldValue.ToString().Substring(0, len) + "...</span>";
									}
									else
									{
										return HttpUtility.HtmlEncode(fieldValue.ToString());
									}
								}
							default:
								return HttpUtility.HtmlEncode(fieldValue.ToString());
						}
					}
					else
					{
						string property = match.Groups[1].Value.Substring(1, match.Groups[1].Value.Length - 1);
						switch (property)
						{
							case "Date":
								{
									if (pi.PropertyType == typeof(DateTime))
									{
										DateTime dt = DateTime.Parse(fieldValue.ToString());
										return HttpUtility.HtmlEncode(dt.ToLongDateString());
									}
									else
									{
										return HttpUtility.HtmlEncode(fieldValue.ToString());
									}
								}
							case "Time":
								{
									if (pi.PropertyType == typeof(DateTime))
									{
										DateTime dt = DateTime.Parse(fieldValue.ToString());
										return HttpUtility.HtmlEncode(dt.ToLongTimeString());
									}
									else
									{
										return HttpUtility.HtmlEncode(fieldValue.ToString());
									}
								}
							default:
								return HttpUtility.HtmlEncode(((DateTime)fieldValue).ToString("f"));
						}
					}
				}
				else
				{
					return HttpUtility.HtmlEncode(fieldValue.ToString());
				}
			};
			ItemTemplate = FieldRegex.Replace(ItemTemplate, fieldMatchEvaluator);

			return ItemTemplate;
		}

		public static string cutStr(string text, int length)
		{
			if (Encoding.Default.GetByteCount(text) < length)
			{
				return text;
			}
			else
			{
				//int c = 0;
				for (int i = 1; i < text.Length; i++)
				{
					string str = text.Substring(0, i);
					if (Encoding.Default.GetByteCount(str) > length - 3)
					{
						return str + "...";
					}
				}
				return text.Substring(0, length);
			}
		}

	}
}
